import 'package:flutter/foundation.dart';
import 'package:lighthouse/pages/function.dart';
import 'package:lighthouse/pages/home.dart';
import 'package:lighthouse/pages/map.dart';
import 'package:lighthouse/pages/me.dart';

//  其他设置
import 'package:lighthouse/pages/me/other_settings.dart';

//  重置密码
import 'package:lighthouse/pages/me/reset_passwords.dart';

//  意见反馈
import 'package:lighthouse/pages/me/feedback.dart';

//  筛选
import 'package:lighthouse/pages/me/screen.dart';

//  忘记密码
import 'package:lighthouse/pages/me/forget_password.dart';

//  忘记密码下一步
import 'package:lighthouse/pages/me/forget_password_next.dart';

import 'index.dart';

typedef PathWidgetBuilder = Widget Function(BuildContext, String);

class Path {
  const Path(this.pattern, this.builder);

  /// A RegEx string for route matching.
  final String pattern;

  /// The builder for the associated pattern route. The first argument is the
  /// [BuildContext] and the second argument a RegEx match if that is included
  /// in the pattern.
  ///
  /// ```dart
  /// Path(
  ///   'r'^/demo/([\w-]+)$',
  ///   (context, matches) => Page(argument: match),
  /// )
  /// ```
  final PathWidgetBuilder builder;
}

class RouteConfiguration {
  static Map<String, WidgetBuilder> routes = {
    "start": (context) => const StartPage(),
    "init_data": (context) => const InitDataPage(),
    "home": (context) => const HomePage(),
    "function": (context) => const FunctionPage(),
    "map": (context) => const MapPage(),
    "me": (context) => const MePage(),
    "login": (context) => const LoginPage(),
    "themes": (context) => const ThemeChangePage(),
    "language": (context) => const LanguagePage(),
    "fontSize": (context) => const FontSizePage(),
    "darkMode": (context) => const DarkModePage(),
    "work_order_list": (context) => const WorkOrderListPage(),
    // "work_order_details": (context) => const WorkOrderDetailsPage(),
    "work_order_add": (context) => WorkOrderAddPage(),
    "otherSettingsPage": (context) => const OtherSettingsPage(),
    "resetPasswordsPage": (context) => const ResetPasswordsPage(),
    "feedbackPage": (context) => const FeedbackPage(),
    "domainSettingsPage": (context) => const DomainPage(),
    "screen": (context) => const ScreenPage(),
    "forgetPassword": (context) => const ForgetPasswordPage(),
    "todo_list": (context) => const TodoPage(),
    // "forgetPasswordNext": (context) => const ForgetPasswordsNextPage(phone: '', username: ''),
  };

  /// List of [Path] to for route matching. When a named route is pushed with
  /// [Navigator.pushNamed], the route name is matched with the [Path.pattern]
  /// in the list below. As soon as there is a match, the associated builder
  /// will be returned. This means that the paths higher up in the list will
  /// take priority.
  static List<Path> paths = [
    //   Path(
    //     r'^' + DemoPage.baseRoute + r'/([\w-]+)$',
    //         (context, match) => DemoPage(slug: match),
    //   ),
    //   Path(
    //     r'^' + rally_routes.homeRoute,
    //         (context, match) => StudyWrapper(
    //       study: DeferredWidget(rally.loadLibrary,
    //               () => rally.RallyApp()), // ignore: prefer_const_constructors
    //     ),
    //   ),
    //   Path(
    //     r'^' + shrine_routes.homeRoute,
    //         (context, match) => StudyWrapper(
    //       study: DeferredWidget(shrine.loadLibrary,
    //               () => shrine.ShrineApp()), // ignore: prefer_const_constructors
    //     ),
    //   ),
    //   Path(
    //     r'^' + crane_routes.defaultRoute,
    //         (context, match) => StudyWrapper(
    //       study: DeferredWidget(crane.loadLibrary,
    //               () => crane.CraneApp(), // ignore: prefer_const_constructors
    //           placeholder: const DeferredLoadingPlaceholder(name: 'Crane')),
    //     ),
    //   ),
    //   Path(
    //     r'^' + fortnightly_routes.defaultRoute,
    //         (context, match) => StudyWrapper(
    //       study: DeferredWidget(
    //           fortnightly.loadLibrary,
    //           // ignore: prefer_const_constructors
    //               () => fortnightly.FortnightlyApp()),
    //     ),
    //   ),
    //   Path(
    //       r'^' + reply_routes.homeRoute,
    //       // ignore: prefer_const_constructors
    //           (context, match) =>
    //       const StudyWrapper(study: reply.ReplyApp(), hasBottomNavBar: true)),
    //   Path(
    //     r'^' + starter_app_routes.defaultRoute,
    //         (context, match) => const StudyWrapper(
    //       study: starter_app.StarterApp(),
    //     ),
    //   ),
    //   Path(
    //     r'^/',
    //         (context, match) => const RootPage(),
    //   ),
  ];

  /// The route generator callback used when the app is navigated to a named
  /// route. Set it on the [MaterialApp.onGenerateRoute] or
  /// [WidgetsApp.onGenerateRoute] to make use of the [paths] for route
  /// matching.
  static Route<dynamic>? onGenerateRoute(RouteSettings settings) {
    for (final path in paths) {
      final regExpPattern = RegExp(path.pattern);
      if (regExpPattern.hasMatch(settings.name!)) {
        final firstMatch = regExpPattern.firstMatch(settings.name!);
        final match =
            (firstMatch?.groupCount == 1) ? firstMatch?.group(1) : null;
        if (kIsWeb) {
          return NoAnimationMaterialPageRoute<void>(
            builder: (context) => path.builder(context, match!),
            settings: settings,
          );
        }
        return MaterialPageRoute<void>(
          builder: (context) => path.builder(context, match!),
          settings: settings,
        );
      }
    }

// If no match was found, we let [WidgetsApp.onUnknownRoute] handle it.
    return null;
  }
}

class NoAnimationMaterialPageRoute<T> extends MaterialPageRoute<T> {
  NoAnimationMaterialPageRoute({
    required WidgetBuilder builder,
    RouteSettings? settings,
  }) : super(builder: builder, settings: settings);

  @override
  Widget buildTransitions(
    BuildContext context,
    Animation<double> animation,
    Animation<double> secondaryAnimation,
    Widget child,
  ) {
    return child;
  }
}
